#ifndef mesgqueue_hpp
#define mesgqueue_hpp
#include <sys/types.h>
#include <sys/ipc.h>
#include <iostream>
#include <unistd.h>
#include <string>
#include <sys/stat.h>
#include <cstring>
#include <sys/msg.h>
using namespace std;

#define pathname "."
#define projid 1234
#define getmsg (IPC_CREAT)
#define creatmsg (IPC_CREAT|IPC_EXCL|0666)

class messagequeue
{
    public:
        messagequeue():_msgid(0)
        {

        }
        void getmsgqueue(int flag)
        {
            key_t key=ftok(pathname,projid);
            if(key==-1)
            {
                cerr<<"ftok error"<<endl;
                exit(1);
            }
            _msgid=msgget(key,flag);
            if(_msgid==-1)
            {
                cerr<<"msgget error"<<endl;
                exit(2);
            }
            cout<<"msg created: "<<_msgid<<endl;
        }
        void send(const int type,const string& text)
        {
            struct msgbuf msg;
            msg.mtype=type;
            memcpy(msg.mtext,text.c_str(),text.size());
            int n=msgsnd(_msgid,&msg,text.size(),0);
            if(n==-1)
            {
                cerr<<"msgsnd error"<<endl;
                return;
            }
        }
        void receive(int type,string& text)
        {
            struct msgbuf msg;
            int n=msgrcv(_msgid,&msg,1024,type,0);
            if(n==-1)
            {
                cerr<<"msgrcv error"<<endl;
                exit(1);
            }
            msg.mtext[n]=0;
            text=msg.mtext;
        }
        void destroy()
        {
            int n=msgctl(_msgid,IPC_RMID,0);
            if(n==-1)
            {
                cerr<<"destroy error"<<endl;
                exit(3);
            }
            cout<<"msgqueue destroyed"<<endl;
        }
        ~messagequeue()
        {
            
        }


    private:
        int _msgid;

};

#define msg_typeserver 2
#define msg_typeclient 1

class Server:public messagequeue
{
public:
    Server()
    {
        messagequeue::getmsgqueue(creatmsg);
    }

    ~Server()
    {
        messagequeue::destroy();
    }
private:

};

class Client:public messagequeue
{
public:
    Client()
    {
        messagequeue::getmsgqueue(getmsg);
    }
    ~Client()
    {
    }
private:

};



#endif